﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using TerminationCall.Core;

namespace TerminationCall.Editor.Controls {

    public partial class TileSetRender : UserControl {

        public event EventHandler<EventArgs> TileSelectionChange;

        private TileSet _tileSet;

        private Bitmap _mainDrawBitmap;
        private Graphics _mainDrawGraphic;
        private Graphics _panelGraphic;

        private Rectangle _selection;

        private bool _mouseDown;

        public TileSet TileSet {
            get {
                return _tileSet;
            }
            set {
                _tileSet = value;
                _selection = Rectangle.Empty;
                _parentTiles.Clear();
                RenderTileSet();
            }
        }

        public Rectangle Selection {
            get {
                return _selection;
            }
            set {
                _selection = value;
                if (TileSelectionChange != null) {
                    TileSelectionChange(this, EventArgs.Empty);
                }
            }
        }

        private Dictionary<Tile, Color> _parentTiles;

        private DifferentColors _differentColors;

        public bool ShowAutoborderGroups { get; set; }
        public bool ShowObjectGroups { get; set; }

        public TileSetRender() {

            InitializeComponent();

            _mainDrawBitmap = new Bitmap(400, 320);
            _mainDrawGraphic = Graphics.FromImage(_mainDrawBitmap);
            _panelGraphic = this.CreateGraphics();

            _differentColors = new DifferentColors();
            _parentTiles = new Dictionary<Tile, Color>();
        }

        private void RenderTileSet() {

            if (_tileSet == null) {
                return;
            }

            _mainDrawGraphic.Clear(Color.White);

            for (int y = 0; y < 20; y++) {
                for (int x = 0; x < 20; x++) {
                    _mainDrawGraphic.DrawImage(_tileSet.Tiles[x, y].Bitmap, new Point(x * 20, y * 16));

                    if (ShowAutoborderGroups) {
                        if (_tileSet.Tiles[x, y].ParentTile != null) {
                            if (!_parentTiles.ContainsKey(_tileSet.Tiles[x, y].ParentTile)) {
                                _parentTiles.Add(_tileSet.Tiles[x, y].ParentTile, _differentColors.TransparentColors[_parentTiles.Count]);
                            }

                            _mainDrawGraphic.FillRectangle(new SolidBrush(_parentTiles[_tileSet.Tiles[x, y].ParentTile]), x * 20, y * 16, TileConstants.TileSizeX, TileConstants.TileSizeY);

                        } else if (_parentTiles.ContainsKey(_tileSet.Tiles[x, y])) {

                            _mainDrawGraphic.FillRectangle(new SolidBrush(_parentTiles[_tileSet.Tiles[x, y]]), x * 20, y * 16, TileConstants.TileSizeX, TileConstants.TileSizeY);

                        }
                    }

                }
            }

            if (ShowObjectGroups) {
                for (int i = 0; i < _tileSet.TileObjectGroups.Count; i++) {
                    _mainDrawGraphic.FillRectangle(new SolidBrush(_differentColors.TransparentColors[i]), _tileSet.TileObjectGroups[i].Rectangle.X * TileConstants.TileSizeX, _tileSet.TileObjectGroups[i].Rectangle.Y * TileConstants.TileSizeY, _tileSet.TileObjectGroups[i].Rectangle.Width * TileConstants.TileSizeX, _tileSet.TileObjectGroups[i].Rectangle.Height * TileConstants.TileSizeY);
                }
            }

            for (int x = 0; x < 20; x++) {
                _mainDrawGraphic.DrawLine(new Pen(Color.FromArgb(50, 0, 0, 0)), x * 20, 0, x * 20, 320);
            }
            for (int y = 0; y < 20; y++) {
                _mainDrawGraphic.DrawLine(new Pen(Color.FromArgb(50, 0, 0, 0)), 0, y * 16, 481, y * 16);
            }

            int choosenTileX = _selection.X * 20;
            int choosenTileY = _selection.Y * 16;
            int choosenTileWidth = _selection.Width;
            int choosenTileHeight = _selection.Height;

            _mainDrawGraphic.DrawLine(new Pen(Color.FromArgb(255, 255, 0, 0)), choosenTileX, choosenTileY, choosenTileX + choosenTileWidth * 20, choosenTileY);
            _mainDrawGraphic.DrawLine(new Pen(Color.FromArgb(255, 255, 0, 0)), choosenTileX, choosenTileY + choosenTileHeight * 16, choosenTileX + choosenTileWidth * 20, choosenTileY + choosenTileHeight * 16);
            _mainDrawGraphic.DrawLine(new Pen(Color.FromArgb(255, 255, 0, 0)), choosenTileX, choosenTileY, choosenTileX, choosenTileY + choosenTileHeight * 16);
            _mainDrawGraphic.DrawLine(new Pen(Color.FromArgb(255, 255, 0, 0)), choosenTileX + choosenTileWidth * 20, choosenTileY, choosenTileX + choosenTileWidth * 20, choosenTileY + choosenTileHeight * 16);

            _panelGraphic.DrawImage(_mainDrawBitmap, new Point());
        }

        private void TileSetRender_MouseMove(object sender, MouseEventArgs e) {

            if (_mouseDown) {
                int x = e.X / 20;
                int y = e.Y / 16;

                if (x >= _selection.X || y >= _selection.Y) {

                    Point point = new Point(_selection.X, _selection.Y);
                    Size size = new Size(x - _selection.X + 1, y - _selection.Y + 1);
                    _selection = new Rectangle(point, size);
                }

            }

            RenderTileSet();

            if (TileSelectionChange != null) {
                TileSelectionChange(this, EventArgs.Empty);
            }
        }

        private void TileSetRender_MouseDown(object sender, MouseEventArgs e) {

            _mouseDown = true;

            int x = e.X / TileConstants.TileSizeX;
            int y = e.Y / TileConstants.TileSizeY;

            _selection = new Rectangle(x, y, 1, 1);

            RenderTileSet();

            if (TileSelectionChange != null) {
                TileSelectionChange(this, EventArgs.Empty);
            }
        }

        private void TileSetRender_MouseUp(object sender, MouseEventArgs e) {

            _mouseDown = false;

        }

        private void TileSetRender_Paint(object sender, PaintEventArgs e) {
            RenderTileSet();
        }

    }

}
